import fft.Field;


public class PrimField extends Field<Integer> {
	private int prim;
	
	public PrimField(int prim) {
		if(prim <= 0)
			throw new IllegalArgumentException("A prim number has to be positive");
		
		this.prim = prim;
	}

	public Integer zero() {
		return 0;
	}

	public Integer one() {
		return 1;
	}
	
	private void checkFieldArgument(Integer a) {
		if(a < 0 || a >= prim)
			throw new IllegalArgumentException("Arguments arent field elements");
	}

	public Integer add(Integer a, Integer b) {
		checkFieldArgument(a);
		checkFieldArgument(b);
		
		return (a + b) % prim;
	}

	public Integer inverseAdd(Integer a) {
		checkFieldArgument(a);
		
		/*
		 * '+ prim' because the modulo in java is sign sensitive,
		 * x % y in [-y+1, .. , 0, .., y-1]
		 * x % y is negative iff x and y have different signs,
		 * this is the case here, by adding 'prim' we get the
		 * mathematical correct modulo.
		 */
		return (-a % prim) + prim;
	}

	public Integer mul(Integer a, Integer b) {
		checkFieldArgument(a);
		checkFieldArgument(b);
		
		return (a * b) % prim;
	}

	public Integer inverseMul(Integer a) {
		checkFieldArgument(a);
		
		if(a == 0)
			throw new IllegalArgumentException("0 has no multiplicative inverse.");
		for(int k = 1; k < prim; k++) {
			/*
			 * the simple modulo works because a and k are positive by definition
			 * of a 'restklassenkoerper'.
			 */
			if((a * k) % prim == 1)
				return k;
		}
		throw new IllegalArgumentException("No inverse found!");
	}
}
